from tkinter import Frame
from tkinter import Label
from tkinter import Entry
from tkinter import StringVar
from tkinter.constants import *
from tkinter import Tk
from tkinter import Button
from tkinter import Text
# from tkinter import Canvas
import tkinter as tk
from tkinter import Scrollbar
from tkinter import Radiobutton
from tkinter import ttk
from tkinter import messagebox
from tkinter.filedialog import *
from remote_update import *
from socket import gethostbyname_ex,gethostname
from os import stat
import time
from text import INFO
from ip_config import * 
from _snmp import *

class Remote(Frame):
    def __init__(self,parent,language):
        super().__init__(parent)
        self.language = language
        self.pathname = StringVar()
        self.pathname.set('')
        self.ipaddr = StringVar()
        self.ipaddr.set('')
        self.ip_config_ipaddr = StringVar()
        self.ip_config_ipaddr.set("192.168.1.1")
        self.local_ipall = gethostbyname_ex(gethostname())
        self.button_per = StringVar()
        self.button_per.set(INFO['Update'][self.language.get()])
        self.iv_hwsel = tk.IntVar()
        self.iv_hwsel.set(1)

        self.strvar_localIP = StringVar()
        self.strvar_localIP.set(INFO['Local IP:'][self.language.get()])
        self.strvar_deviceIP = StringVar()
        self.strvar_deviceIP.set(INFO['Device IP:'][self.language.get()])
        self.strvar_Progress = StringVar()
        self.strvar_Progress.set(INFO['Progress:'][self.language.get()])
        self._strvar_Progress = StringVar()
        self._strvar_Progress.set("0%")

        self.all_strvar_Progress = StringVar()
        self.all_strvar_Progress.set(INFO['All_Progress:'][self.language.get()])
        self._all_strvar_Progress = StringVar()
        self._all_strvar_Progress.set("0%")

        self.strvar_chooseFile = StringVar()
        self.strvar_chooseFile.set(INFO['Choose File'][self.language.get()])

        self.ip_config_label = StringVar()
        self.ip_config_label.set(INFO['Serial Port'][self.language.get()])

        self.ip_config_but = StringVar()
        self.ip_config_but.set(INFO['update port'][self.language.get()])

        self.ip_config_set = StringVar()
        self.ip_config_set.set(INFO['Set ip'][self.language.get()])

        self.snmp_oid = StringVar()
        self.snmp_host = StringVar()
        self.snmp_type = StringVar()
        self.snmp_type.set("i")
        self.snmp_value = StringVar()

        self.ip_config_but_r = StringVar()
        self.ip_config_but_r.set(INFO['Read IP'][self.language.get()])
        self.ip_config_but_w = StringVar()
        self.ip_config_but_w.set(INFO['Write IP'][self.language.get()])

        
        if len(port_list()) > 0:
            self.Serial_port = list(port_list().values())[0]
        else:
            self.Serial_port = ""
        self.display()
        self.pack(anchor=CENTER)



    def choose_file(self):
        if self.iv_hwsel.get() == 3:
            ret = askopenfile(title=INFO['please choose updatefile'][self.language.get()],initialdir='.',filetypes=[('snmp MiB file','*.txt')])
        else:
            ret = askopenfile(title=INFO['please choose updatefile'][self.language.get()],initialdir='.',filetypes=[('binary file','*.bin')])
        if ret :
            print(ret.name)
            self.pathname.set(ret.name)
        else:
            self.pathname.set('')

    def start_update(self):
        # print(stat(self.pathname.get()).st_size)
        self.beginbut.config(state = 'disable')
        self.pb['value'] = 0
        self.all_pb['value'] = 0
        self.update()


        # testfunc(self,self.button_per,self.localip, self.ipaddr.get(), self.pathname.get(),self.pb)
        localip_init = list(map(int,self.localip.split(".")))
        if self.pathname.get() == '':
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please choose firmware file first'][self.language.get()])
        elif (self.iv_hwsel.get() == 1) & ((stat(self.pathname.get()).st_size > 1600000) | (stat(self.pathname.get()).st_size < 1400000)):
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please choose correct firmware file'][self.language.get()])
        elif (self.iv_hwsel.get() == 2) & ((stat(self.pathname.get()).st_size > 2300000) | (stat(self.pathname.get()).st_size < 2100000)):
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please choose correct firmware file'][self.language.get()])
        elif self.ipaddr.get() == '' or '.' in self.ipaddr.get() or '，' in self.ipaddr.get():
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input correct IPaddress,example:1,1-10,20'][self.language.get()])
        # elif (len(ipaddr_int) != 4) | (max(ipaddr_int) > 255):
        #     messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input correct IPaddress'][self.language.get()])
        # elif (self.localip.split('.')[0:3] != self.ipaddr.get().split('.')[0:3]):
        #     messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input correct IPaddress or Choose correct NIC'][self.language.get()])
        # elif len(self.ipaddr.get().split('-')) >= 2:
        #     end_ipaddr = int(self.ipaddr.get().split('-')[-1])
        #     if (end_ipaddr >= 255):
        #         messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input correct IPaddress ,example:192.168.1.1-254'][self.language.get()])
        #     elif(ipaddr_int[3] >= end_ipaddr):
        #         messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input correct IPaddress ,example:192.168.1.1-1 is Field'][self.language.get()])
        #     else:
        #         ret = program__wr_mini_thread(self,self.button_per,self.localip, ipaddr_int,end_ipaddr, self.pathname.get(),self.pb,self.iv_hwsel.get())
        else:
            if not "-" in self.ipaddr.get() and not "," in self.ipaddr.get():
                if 0 < int(self.ipaddr.get()) < 255:
                    self._all_strvar_Progress.set("1%")
                    ret = program_wr_mini(self,self._strvar_Progress,self.localip,"{}.{}.{}.{}".format(*localip_init[0:3],self.ipaddr.get()), self.pathname.get(),self.pb,self.iv_hwsel.get())
                    if ret == 0:
                        self.all_pb["value"] = 100
                        self._all_strvar_Progress.set("100%")
                        self.button_per.set("已完成")
                        messagebox.showinfo(title=INFO['Message'][self.language.get()],message='firmware update successed')
                    elif ret == 1:
                        messagebox.showerror(title=INFO['Failure'][self.language.get()],message='connected failed! please check IPaddress')
                    elif ret == 2:
                        messagebox.showerror(title=INFO['Failure'][self.language.get()],message='flash erase failed! please try again later')
                    else:
                        messagebox.showerror(title=INFO['Failure'][self.language.get()],message='firmware update failed! please try again later')
                else:
                    messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input correct IPaddress,0 < ip < 255'][self.language.get()])
            else:
                flag = True
                ip_list = []
                datas = self.ipaddr.get().split(",")
                for data in datas:
                    if data != "":
                        if "-" in data:
                            _data = data.split("-")
                            start_ip = _data[0]
                            end_ip = _data[1]
                            if 0 < int(start_ip) < int(end_ip) < 255:
                                ip_list = ip_list + ["{}.{}.{}.{}".format(*localip_init[0:3],i) for i in range(int(start_ip),int(end_ip)+1,1)]
                            else:
                                flag = False
                                messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input correct IPaddress,0 < start_ip < end_ip < 255'][self.language.get()])
                                break
                        else:
                            if 0 < int(data) < 255:
                                ip_list.append("{}.{}.{}.{}".format(*localip_init[0:3],data))
                            else:
                                flag = False
                                messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input correct IPaddress,0 < ip < 255'][self.language.get()])
                                break
                if flag:
                    ip_dst = list(set(ip_list))
                    ip_dst.sort()
                    ret = program__wr_mini_thread(self,self._strvar_Progress,self.button_per,self.localip, ip_dst, self.pathname.get(),self.pb,self.iv_hwsel.get(),self.all_pb,self._all_strvar_Progress)
                    if ret == 0:
                        self.all_pb["value"] = 100
                        self._all_strvar_Progress.set("100%")
                        self.button_per.set("已全部完成")
                        messagebox.showinfo(title=INFO['Message'][self.language.get()],message='firmware update successed')
                    elif ret == 1:
                        messagebox.showerror(title=INFO['Failure'][self.language.get()],message='connected failed! please check IPaddress')
                    elif ret == 2:
                        messagebox.showerror(title=INFO['Failure'][self.language.get()],message='flash erase failed! please try again later')
                    else:
                        messagebox.showerror(title=INFO['Failure'][self.language.get()],message='firmware update failed! please try again later')

        self.update()
        self.button_per.set(INFO['Update'][self.language.get()])
        self.beginbut.config(state='normal')

    def start_port_update(self,*args):
        self.ip_config_comb['values'] = tuple(port_list().keys())
    def combselect(self,*args):
        self.localip = self.comb.get()
        # print(self.comb.get())
        # localip_int = list(map(int,self.localip.split('-')[0].split('.')))
        # self.ipaddr.set("{}.{}.{}.0".format(*localip_int[0:3]))

    def ip_config_combselect(self,*args):
        self.Serial_port = port_list()[self.ip_config_comb.get()]
        
    def f_hw_sel(self):
        if self.iv_hwsel.get() == 3:
            self.Text.insert("1.0",INFO['This feature requires the installation of the SNMP command-line tool.'][self.language.get()]+"\n")

    def read_ip(self):
        if self.ip_config_comb.get() == '':
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please choose Serial Port first'][self.language.get()])
        else:
            ip_config_read(self,self.Serial_port,self.Text)
    def write_ip(self):
        set_ip_int = list(map(int,self.ip_config_ipaddr.get().split(".")))
        
        if self.ip_config_comb.get() == '':
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please choose Serial Port first'][self.language.get()])
        elif (len(set_ip_int) != 4) | (max(set_ip_int) > 255):
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input correct IPaddress'][self.language.get()])
        else:
            ip_config(self,self.ip_config_ipaddr.get(),self.Serial_port,self.Text)

    def snmp_get(self):
        if not self.iv_hwsel.get() == 3:
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please select SNMP-MIB file'][self.language.get()])
        elif self.pathname.get() == '':
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please select SNMP-MIB file'][self.language.get()])
        elif len(self.snmp_oid.get()) == 0:
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input SNMP oidname'][self.language.get()])
        elif len(self.snmp_host.get()) == 0:
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please select SNMP host'][self.language.get()])
        else:
            result = snmpget(file_path=self.pathname.get(),OIDname=self.snmp_oid.get(),host=self.snmp_host.get())
            
            self.Text.insert("1.0",str(result)+"\n")
    def snmp_set(self):
        if not self.iv_hwsel.get() == 3:
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please select SNMP-MIB file'][self.language.get()])
        elif self.pathname.get() == '':
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please select SNMP-MIB file'][self.language.get()])
        elif len(self.snmp_oid.get()) == 0:
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please input SNMP oidname'][self.language.get()])
        elif len(self.snmp_host.get()) == 0:
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please select SNMP host'][self.language.get()])
        elif len(self.snmp_type.get()) == 0:
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please select SNMP type'][self.language.get()])
        elif len(self.snmp_value.get()) == 0:
            messagebox.showwarning(title=INFO['Error'][self.language.get()],message=INFO['please select SNMP set value'][self.language.get()])
        else:
            result = snmpset(file_path=self.pathname.get(),OIDname=self.snmp_oid.get(),host=self.snmp_host.get(),set_type=self.snmp_type.get(),set_value=self.snmp_value.get())
            self.Text.insert("1.0",str(result)+"\n")
    def display(self):
        f_hwsel = Frame(self)
        f_hwsel.grid(row=0, column=0, columnspan = 3,padx=10, pady=5)
        Radiobutton(f_hwsel, text='CUTE-DP & CUTE-mini', font=('Arial', 12), variable=self.iv_hwsel, value=1, width=20, command=self.f_hw_sel).grid(row=1,column=1,pady = 10)
        Radiobutton(f_hwsel, text='CUTE-A7', font=('Arial', 12), variable=self.iv_hwsel, value=2, width=20, command=self.f_hw_sel).grid(row=1,column=2,pady = 10)
        Radiobutton(f_hwsel, text='SNMP-MIB', font=('Arial', 12), variable=self.iv_hwsel, value=3, width=20, command=self.f_hw_sel).grid(row=1,column=3,pady = 10)
        # Label(f_hwsel, text='进度:', font=('宋体', 12)).grid(row=0, column=0, sticky='e', padx=10, pady=10)

        #choose firmware file
        Label(self,textvariable=self.pathname,font=('Arial',12),bg='white',width=50,height=2,wraplength = 450,justify='left').\
            grid(row=2,column=1,columnspan = 2,padx = 10,pady = 10)
        Button(self,textvariable=self.strvar_chooseFile,width=10,height=1,command = self.choose_file).\
            grid(row=2,column=0,padx = 10,pady = 10)

        # select local computer IP

        Label(self,textvariable=self.strvar_localIP,font=('Arial',12)).\
            grid(row=3,column=0,sticky='e',padx = 10,pady = 10)
        self.comb = ttk.Combobox(self, font=('Arial',12), values = tuple(self.local_ipall[2]))
        self.comb.grid(row=3,column=1,sticky='w',padx = 10,pady = 10)
        self.comb.current(0)
        self.localip = self.comb.get()
        self.comb.bind("<<ComboboxSelected>>",self.combselect)

        #input WR node IP
        self.entry = Entry(self,textvariable=self.ipaddr,width=20,font=('Arial',12))
        self.entry.grid(row=4,column=1,sticky='w',padx = 10,pady = 10)
        Label(self, textvariable=self.strvar_deviceIP, font=('Arial', 12)).\
            grid(row=4, column=0, sticky='e',padx = 10,pady = 10)

        #processing persent
        Label(self, textvariable=self.strvar_Progress, font=('Arial', 12)).\
            grid(row=5, column=0, sticky='e',padx = 10,pady = 10)
        self.pb = ttk.Progressbar(self, length=400, value=0, mode='determinate')
        self.pb.grid(row=5,column=1,sticky='w',columnspan = 2,padx = 10,pady = 10)
        Label(self, textvariable=self._strvar_Progress, font=('Arial', 12)).\
            grid(row=5, column=2, sticky='e',padx = 10,pady = 10)
        
        #processing persent
        Label(self, textvariable=self.all_strvar_Progress, font=('Arial', 12)).\
            grid(row=6, column=0, sticky='e',padx = 10,pady = 10)
        self.all_pb = ttk.Progressbar(self, length=400, value=0, mode='determinate')
        self.all_pb.grid(row=6,column=1,sticky='w',columnspan = 2,padx = 10,pady = 10)
        Label(self, textvariable=self._all_strvar_Progress, font=('Arial', 12)).\
            grid(row=6, column=2, sticky='e',padx = 10,pady = 10)

        #begin update
        self.beginbut = Button(self,textvariable=self.button_per,width=40,height=2,command = self.start_update)
        self.beginbut.grid(row=7,column=0,columnspan = 3,padx = 10,pady = 10)

        Label(self,textvariable=self.ip_config_label,font=('Arial',12)).\
            grid(row=8,column=0,sticky='e',padx = 10,pady = 10)
        self.ip_config_comb = ttk.Combobox(self, font=('Arial',12),width=35, values = tuple(port_list().keys()))
        if len(port_list()) > 0: self.ip_config_comb.current(0)
        self.ip_config_comb.grid(row=8,column=1,sticky='w',padx = 10,pady = 10)
        self.ip_config_comb.bind("<<ComboboxSelected>>",self.ip_config_combselect)
        self.beginbut = Button(self,textvariable=self.ip_config_but,width=10,command = self.start_port_update)
        self.beginbut.grid(row=8,column=2,columnspan = 3,padx = 10,pady = 10)

        # 设定IP
        Label(self, textvariable=self.ip_config_set, font=('Arial', 12)).\
            grid(row=9, column=0, sticky='e',padx = 10,pady = 10)
        self.ip_config_entry = Entry(self,textvariable=self.ip_config_ipaddr,width=20,font=('Arial',12))
        self.ip_config_entry.grid(row=9,column=1,sticky='w',padx = 10,pady = 10)

        #begin update
        self.beginbut = Button(self,textvariable=self.ip_config_but_r,width=10,height=1,command = self.read_ip)
        self.beginbut.grid(row=10,column=0,columnspan = 2,padx = 5,pady = 10)

        #begin update
        self.beginbut = Button(self,textvariable=self.ip_config_but_w,width=10,height=1,command = self.write_ip)
        self.beginbut.grid(row=10,column=1,columnspan = 2,padx = 5,pady = 10)
        

        # 设定IP
        Label(self, text="OID Name:", font=('Arial', 12)).\
            grid(row=11, column=0, sticky='e',pady = 10)
        self.snmp_oid_entry = Entry(self,textvariable=self.snmp_oid,width=15,font=('Arial',12)).grid(row=11,column=1,sticky='w',pady = 10)

        Label(self, text="HOST:", font=('Arial', 12)).\
            grid(row=11, column=1, sticky='e',pady = 10)
        self.snmp_host_entry = Entry(self,textvariable=self.snmp_host,width=15,font=('Arial',12)).grid(row=11,column=2,sticky='w',pady = 10)

        Label(self, text="Type:", font=('Arial', 12)).\
            grid(row=12, column=0, sticky='e',pady = 10)
        f_Radio = Frame(self)
        f_Radio.grid(row=12, column=1, columnspan = 3,sticky='w', pady=5)
        tk.Radiobutton(f_Radio, text="i", variable=self.snmp_type, value="i", font=('Arial', 12)).grid(row=12,column=0,pady = 10)
        tk.Radiobutton(f_Radio, text="u", variable=self.snmp_type, value="u", font=('Arial', 12)).grid(row=12,column=1,pady = 10)
        tk.Radiobutton(f_Radio, text="s", variable=self.snmp_type, value="s", font=('Arial', 12)).grid(row=12,column=2,pady = 10)


        Label(self, text="Set Value:", font=('Arial', 12)).\
            grid(row=12, column=1, sticky='e',pady = 10)
        self.snmp_value_entry = Entry(self,textvariable=self.snmp_value,width=15,font=('Arial',12)).grid(row=12,column=2,sticky='w',pady = 10)


        #begin update
        self.beginbut = Button(self,text="SNMP Get",width=10,height=1,command = self.snmp_get)
        self.beginbut.grid(row=13,column=0,columnspan = 2,padx = 10,pady = 5)
        #begin update
        self.beginbut = Button(self,text="SNMP Set",width=10,height=1,command = self.snmp_set)
        self.beginbut.grid(row=13,column=1,columnspan = 2,padx = 10,pady = 5)

        

        
        

        self.Text = Text(self, width=90, height=8)
        self.Text.grid(row=14,column=0,columnspan = 3,padx = 10,pady = 10)

if __name__ == '__main__':

    top = Tk()

    remote = Remote(top)
    top.mainloop()